<template>
  <ElRow :gutter="20" justify="space-between">
    <ElCol :xl="12" :lg="12" :md="24" :sm="24" :xs="24">
      <ElCard shadow="hover" class="mb-20px">
        <ElSkeleton :loading="loading" animated>
          <Echart :options="lineOptionsData" :height="300" />
        </ElSkeleton>
      </ElCard>
    </ElCol>
    <ElCol :xl="12" :lg="12" :md="24" :sm="24" :xs="24">
      <ElCard shadow="hover" class="mb-20px">
        <ElSkeleton :loading="loading" animated>
          <Echart :options="RLineOptionsData" :height="300" />
        </ElSkeleton>
      </ElCard>
    </ElCol>
  </ElRow>
  <ElCard shadow="hover" class="mb-20px">
    <div> Redis 详细信息 </div>
    <el-table v-loading="tableLoading" :data="tableData">
      <el-table-column prop="key" label="Key" />
      <el-table-column prop="description" label="Description" />
      <el-table-column prop="value" label="Value" />
    </el-table>
  </ElCard>
</template>

<script setup lang="ts" name="lineChart">
import moment from 'moment'
import { ElCol, ElCard, ElSkeleton } from 'element-plus'
import { Echart } from '@/components/Echart'
import { lineOptions, RLineOptions } from './echarts-data'
import { ref, reactive, onMounted, onDeactivated } from 'vue'
import { useRoute } from 'vue-router'
import { getRedisKeysSizeApi, getRedisMemoryInfoApi, getRedisInfoApi } from '@/api/modules/monitor'
import { set } from 'lodash-es'
import { EChartsOption } from 'echarts'
import { useI18n } from '@/hooks/web/useI18n'

const { t } = useI18n()

const loading = ref(true)
const route = useRoute()

const url = reactive({
  keysSize: '/sys/actuator/redis/keysSize',
  memoryInfo: '/sys/actuator/redis/memoryInfo',
  info: '/sys/actuator/redis/info'
})
const service = {
  name: t('redisInfo.ram'),
  type: 'line',
  data: [],
  areaStyle: {}
}
const RService = {
  name: t('redisInfo.ram'),
  type: 'line',
  data: [],
  areaStyle: {},
  itemStyle: {
    normal: {
      color: '#F29C1B',
      lineStyle: {
        color: '#F29C1B'
      }
    }
  }
}
onMounted(() => {
  openTimer()
  loadRedisInfo() // table数据
  setTimeout(() => {
    loadData()
  }, 1000)
})
const lineOptionsData = reactive<EChartsOption>(lineOptions) as EChartsOption
const RLineOptionsData = reactive<EChartsOption>(RLineOptions) as EChartsOption
// 定时器
let timer: NodeJS.Timer | null = null
const openTimer = () => {
  loadData()
  closeTimer()
  timer = setInterval(() => {
    if (route.path === '/supervisory/monitor/redis') {
      loadData()
    }
  }, 3000)
}
// 关闭定时器
const closeTimer = () => {
  if (timer) clearInterval(timer)
}
// x,y轴 的数据
const objData = ref({ x: [], y: [], y1: [] })
// 最大最小值
const objMaxAndMin = ref({ max: 0, min: 0 })
// 请求数据

const loadData = async () => {
  const res = await Promise.all([
    getRedisKeysSizeApi(url.keysSize),
    getRedisMemoryInfoApi(url.memoryInfo)
  ])
  loading.value = false
  let [{ dbSize }, { used_memory }] = res
  if (res) {
    const times = moment(moment().valueOf()).format('hh:mm:ss')
    // @ts-expect-error
    objData.value.x.push(times)
    // @ts-expect-error
    objData.value.y.push(+used_memory / 1000)
    // @ts-expect-error
    objData.value.y1.push(dbSize)
    if (objData.value.x.length > 6) {
      objData.value.x.splice(0, 1)
      objData.value.y.splice(0, 1)
      objData.value.y1.splice(0, 1)
    }
    service.data = objData.value.y
    RService.data = objData.value.y1
    set(lineOptionsData, 'xAxis.data', objData.value.x)
    set(RLineOptionsData, 'xAxis.data', objData.value.x)
    set(lineOptionsData, 'series', [service])
    set(RLineOptionsData, 'series', [RService])
    // 左侧计算 Key 最大最小值
    let keyPole = getMaxAndMin(objData.value.y)
    // @ts-expect-error
    objMaxAndMin.value.max = Math.floor(keyPole[0]) + 10
    // @ts-expect-error
    objMaxAndMin.value.min = Math.floor(keyPole[1]) - 10
    if (objMaxAndMin.value.min < 0) objMaxAndMin.value.min = 0
    set(lineOptionsData, 'yAxis.min', objMaxAndMin.value.min)
    set(lineOptionsData, 'yAxis.max', objMaxAndMin.value.max)

    // 右侧计算 Key 最大最小值
    let RKeyPole = getMaxAndMin(objData.value.y1)
    // @ts-expect-error
    objMaxAndMin.value.max = Math.floor(RKeyPole[0]) + 10
    // @ts-expect-error
    objMaxAndMin.value.min = Math.floor(RKeyPole[1]) - 10
    if (objMaxAndMin.value.min < 0) objMaxAndMin.value.min = 0
    set(RLineOptionsData, 'yAxis.min', objMaxAndMin.value.min)
    set(RLineOptionsData, 'yAxis.max', objMaxAndMin.value.max)
  }
}
// 获取table数据
const tableLoading = ref(false)
const tableData = ref([])
const loadRedisInfo = async () => {
  tableLoading.value = true
  const res = await getRedisInfoApi(url.info).finally(() => {
    tableLoading.value = false
  })
  tableData.value = res.result
}
// 销毁定时器
onDeactivated(() => {
  closeTimer()
})
// // 获取一组数据中最大和最小的值
const getMaxAndMin = (dataSource) => {
  let maxValue: number | null = null,
    minValue: number | null = null
  dataSource.forEach((item) => {
    let value = Number.parseInt(item)
    // max
    if (maxValue == null) {
      maxValue = value
    } else if (value > maxValue) {
      maxValue = value
    }
    // min
    if (minValue == null) {
      minValue = value
    } else if (value < minValue) {
      minValue = value
    }
  })
  return [maxValue, minValue]
}
</script>
